#ifndef __SERIALIZABLE_H__
  #define __SERIALIZABLE_H__

#include <string>

#include "converter.h"

using namespace std;

// help macros for normal member(s)
#define DESERIALIZE(output) deserialize(output, #output)
#define SERIALIZE(value) serialize(#value, value)

// help macros for member(s) that use property class (property pattern)
#define DESERIALIZE_PROPERTY(a) deserialize(*a, #a)
#define SERIALIZE_PROPERTY(a) serialize(#a, a())

//! Serializable interface for storing or loading data to and from different medias

/*!
This class is a pure virtual interface for serializing objects.
The idea behind this interface is to have the same interface for serializing objects to different types of systems
like ini or XML or database or ...

Implementation date: 2008

Usage:

This class is a pure virtual interface and cannot be used alone.
*/

class serializable {
private:
  //! assignment operator: not allowed
  serializable &operator=(const serializable &s);

  //! copy constructor: not allowed
  serializable(const serializable &s);

protected:
  //! name of the class to serialize / deserialize
  const char * const class_name;

  //! whether the data is already loaded from file, database, or ...
  bool loaded;

  //! must be overridden by the sub-class to load data
  virtual void load() = 0;

  //! must be overridden by the sub-class to persist data
  virtual void persist(bool requires_lock = true) = 0;

  //! constructor
  serializable(const char * const class_name) : class_name(class_name), loaded(false) {
    // nothing to do
  }

  //! destructor
  virtual ~serializable() {
    // nothing to do
  }

public:
  //! returns the name of the class to be serialized / deserialized
  const char *get_class_name() const {
    return class_name;
  }

  //! resets the loaded variable to false, this should cause a reload by the next call of deserialize
  void reset() {
    loaded = false; // will be used in sub-classes to reload the data when calling deserialize
  }
};

#endif
